Fix rerunning rustdoc when output deleted
authorAlex Crichton <alex@alexcrichton.com>
Tue, 8 Mar 2016 05:51:44 +0000 (21:51 -0800)
committerAlex Crichton <alex@alexcrichton.com>
Tue, 8 Mar 2016 05:52:32 +0000 (21:52 -0800)
If `crate/index.html` is missing, we need to rerun rustdoc!

Closes #2379

src/cargo/ops/cargo_rustc/context.rs
src/cargo/ops/cargo_rustc/fingerprint.rs
src/cargo/ops/cargo_rustc/layout.rs
src/cargo/ops/cargo_rustc/mod.rs
tests/test_cargo_doc.rs

index 8d88ac384cc3448eaab138fef26348acdaa02b49..b350ba6efad3778011137531091153523bcfd837 100644 (file)
@@ -213,7 +213,11 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
     /// Returns the appropriate output directory for the specified package and
     /// target.
     pub fn out_dir(&self, unit: &Unit) -> PathBuf {
-        self.layout(unit.pkg, unit.kind).out_dir(unit.pkg, unit.target)
+        if unit.profile.doc {
+            self.layout(unit.pkg, unit.kind).doc_root()
+        } else {
+            self.layout(unit.pkg, unit.kind).out_dir(unit.pkg, unit.target)
+        }
     }
 
     /// Return the (prefix, suffix) pair for dynamic libraries.
index d0007f52dcdfa80275c0f51b1055a779d8cb9b62..837b14bc113356c8ff759e348c5d39b5ee8b7351 100644 (file)
@@ -59,7 +59,10 @@ pub fn prepare_target<'a, 'cfg>(cx: &mut Context<'a, 'cfg>,
 
     let root = cx.out_dir(unit);
     let mut missing_outputs = false;
-    if !unit.profile.doc {
+    if unit.profile.doc {
+        missing_outputs = !root.join(unit.target.crate_name())
+                               .join("index.html").exists();
+    } else {
         for filename in try!(cx.target_filenames(unit)).iter() {
             missing_outputs |= fs::metadata(root.join(filename)).is_err();
         }
index d25a8199d1a47c9918e640bf8aa3f5afc267cb53..4add3a7586356e01bc063ed54c5d290c3196ed97 100644 (file)
@@ -165,4 +165,10 @@ impl<'a> LayoutProxy<'a> {
             self.root().to_path_buf()
         }
     }
+
+    pub fn doc_root(&self) -> PathBuf {
+        // the "root" directory ends in 'debug' or 'release', and we want it to
+        // end in 'doc' instead
+        self.root.root().parent().unwrap().join("doc")
+    }
 }
index b71da0fcc4339431b0f003a9836720eb0f85be04..dad110c208e64b93a7338d28cef0c799d30e5fd7 100644 (file)
@@ -374,10 +374,7 @@ fn rustdoc(cx: &mut Context, unit: &Unit) -> CargoResult<Work> {
         rustdoc.arg("--target").arg(target);
     }
 
-    // the "root" directory ends in 'debug' or 'release', and we want it to end
-    // in 'doc' instead
-    let doc_dir = cx.layout(unit.pkg, unit.kind).proxy().root();
-    let doc_dir = doc_dir.parent().unwrap().join("doc");
+    let doc_dir = cx.out_dir(unit);
 
     // Create the documentation directory ahead of time as rustdoc currently has
     // a bug where concurrent invocations will race to create this directory if
index a53a621202f300c9d6366337e9e88ae1cc1982c8..6bc412b437b306a421c917e1f2869673f2a38d49 100644 (file)
@@ -1,4 +1,5 @@
 use std::str;
+use std::fs;
 
 use support::{project, execs, path2url};
 use support::{COMPILING, DOCUMENTING, RUNNING};
@@ -525,3 +526,26 @@ test!(features {
     assert_that(&p.root().join("target/doc/foo/fn.foo.html"), existing_file());
     assert_that(&p.root().join("target/doc/bar/fn.bar.html"), existing_file());
 });
+
+test!(rerun_when_dir_removed {
+    let p = project("foo")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "foo"
+            version = "0.0.1"
+            authors = []
+        "#)
+        .file("src/lib.rs", r#"
+            /// dox
+            pub fn foo() {}
+        "#);
+    assert_that(p.cargo_process("doc"),
+                execs().with_status(0));
+    assert_that(&p.root().join("target/doc/foo/index.html"), existing_file());
+
+    fs::remove_dir_all(p.root().join("target/doc/foo")).unwrap();
+
+    assert_that(p.cargo_process("doc"),
+                execs().with_status(0));
+    assert_that(&p.root().join("target/doc/foo/index.html"), existing_file());
+});